package com.zmj.sy.mom.srv.aps.bean.vo.base;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;


@Getter
@Setter
public class BasePageReqVo {

    @ApiModelProperty("当前页")
    private int page = 1;

    @ApiModelProperty("每页记录数")
    private int size = 10;

    private String sort;

    private String order;

    private List<SearchParam> searchParams = new ArrayList<>();

    public <T> Page<T> toPage() {
        return new Page<>(page, size);
    }

    public QueryWrapper<?> query() {
        return query(null);
    }

    public QueryWrapper<?> query(Map<String, String> mapping, String... ignore) {
        List<String> ignores = new ArrayList<>();
        if(CollUtil.isEmpty(ignores)){
            ignores = Arrays.asList(ignore);
        }

        QueryWrapper<?> query = Wrappers.query();
        for (SearchParam searchParam : searchParams) {
            String key = searchParam.getKey();
            if (ignores.contains(key)) {
                continue;
            }
            if (CollUtil.isNotEmpty(mapping) && mapping.containsKey(key)) {
                key = mapping.get(searchParam.getKey());
            } else {
                key = com.baomidou.mybatisplus.core.toolkit.StringUtils.camelToUnderline(searchParam.getKey());
            }
            if (searchParam.getType().equals("date:single")) {
                query.eq("DATE(" + key + ")", searchParam.getValue());
            } else if (searchParam.getType().equals("date:multiple")) {
                query.in("DATE(" + key + ")", Arrays.asList(searchParam.getValue().split(",")));
            } else if (searchParam.getType().equals("date:range")) {
                List<String> date = Arrays.asList(searchParam.getValue().split(","));
                date.sort(String::compareTo);
                query.ge("DATE(" + key + ")", date.get(0));
                query.le("DATE(" + key + ")", date.get(1));
            } else if (searchParam.getType().equals("number:eq")) {
                query.eq(key, Integer.valueOf(searchParam.getValue()));
            } else if (searchParam.getType().equals("number:ne")) {
                String keyFinal = key;
                query.nested(qw->{
                    qw.ne(keyFinal, Integer.valueOf(searchParam.getValue()))
                    .or()
                    .isNull(keyFinal);
                });
            } else if (searchParam.getType().equals("number:gt")) {
                query.gt(key, Integer.valueOf(searchParam.getValue()));
            } else if (searchParam.getType().equals("number:ge")) {
                query.ge(key, Integer.valueOf(searchParam.getValue()));
            } else if (searchParam.getType().equals("number:lt")) {
                query.lt(key, Integer.valueOf(searchParam.getValue()));
            } else if (searchParam.getType().equals("number:le")) {
                query.le(key, Integer.valueOf(searchParam.getValue()));
            } else if (searchParam.getType().equals("number:between")) {
                List<Integer> date = Arrays.stream(searchParam.getValue().split(",")).map(Integer::valueOf).sorted().collect(Collectors.toList());
                query.ge(key, date.get(0));
                query.le(key, date.get(1));
            } else if (searchParam.getType().equals("number:notBetween")) {
                List<Integer> date = Arrays.stream(searchParam.getValue().split(",")).map(Integer::valueOf).sorted().collect(Collectors.toList());
                String keyFinal = key;
                query.and(queryWrapper ->{
                    queryWrapper.lt(keyFinal, date.get(0));
                    queryWrapper.or();
                    queryWrapper.gt(keyFinal, date.get(1));
                });

            } else if (searchParam.getType().equals("string:eq")) {
                query.eq(key, searchParam.getValue());
            } else if (searchParam.getType().equals("string:ne")) {
                String keyFinal = key;
                query.nested(qw->{
                    qw.ne(keyFinal, Integer.valueOf(searchParam.getValue()))
                            .or()
                            .isNull(keyFinal);
                });
            } else if (searchParam.getType().equals("string:like")) {
                query.like(key, searchParam.getValue());
            } else if (searchParam.getType().equals("string:notLike")) {
                query.notLike(key, searchParam.getValue());
            } else if (searchParam.getType().equals("string:startWith")) {
                query.likeRight(key, searchParam.getValue());
            } else if (searchParam.getType().equals("string:endWith")) {
                query.likeLeft(key, searchParam.getValue());
            }

        }

        if (StringUtils.hasText(sort) && StringUtils.hasText(order)) {
            String key = sort;
            if (CollUtil.isNotEmpty(mapping) && mapping.containsKey(sort)) {
                key = mapping.get(sort);
            }
            query.orderBy(true, "asc".equals(order), key);
        }
        return query;
    }

}
